package com.example.makerspace.service.impl;
import com.example.makerspace.dao.OrganizeDAO;
import com.example.makerspace.dao.OrganizeProjectDAO;
import com.example.makerspace.dao.UserDAO;
import com.example.makerspace.dao.UserProjectDAO;
import com.example.makerspace.domain.OrganizeDO;
import com.example.makerspace.domain.OrganizeProjectDO;
import com.example.makerspace.domain.UserDO;
import com.example.makerspace.domain.UserProjectDO;
import com.example.makerspace.dto.Result;
import com.example.makerspace.dto.organizeDTO.OrganizeDTO;
import com.example.makerspace.enums.ResultCodeEnum;
import com.example.makerspace.service.OrganizeService;
import com.example.makerspace.utils.DateUtils;
import com.example.makerspace.utils.FileUtils;
import com.example.makerspace.utils.JwtUtils;
import com.example.makerspace.utils.ValidateCodeUtils;
import com.example.makerspace.vo.OrganizationProjectVO;
import com.example.makerspace.vo.OrganizationVO;
import org.apache.commons.lang.StringUtils;
import org.gitlab4j.api.GitLabApi;
import org.gitlab4j.api.GitLabApiException;
import org.gitlab4j.api.models.Commit;
import org.gitlab4j.api.models.Project;
import org.gitlab4j.api.models.Visibility;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

import static com.example.makerspace.cache.GitLabConstants.*;

@Service
public class OrganizeServiceImpI implements OrganizeService {

    private  final  static  String   testHttpPrefix="https://119.45.199.13:3035/static/";

    private final static String RESOURCE_PATH_PREFIX = "resource/";
    private  final  static  String  devHttpPrefix="https://nism.ytcata.com:443/static/";

    @Resource
    private OrganizeDAO organizeDAO;

    @Resource
    private UserDAO userDAO;

    @Resource
    private UserProjectDAO userProjectDAO;


    @Resource
    private OrganizeProjectDAO organizeProjectDAO;
    @Override
    public Result createOrganize(OrganizeDTO organizeDTO) {
        ArrayList<String> arr = new ArrayList<>();
        OrganizeDO organizeDO = new OrganizeDO();
        organizeDO.setOrganizePeople(arr);
        BeanUtils.copyProperties(organizeDTO,organizeDO);
        organizeDAO.insert(organizeDO);
        return Result.success("创建组织成功");
    }

    @Override
    public Result updateOrganize(OrganizeDTO organizeDTO) {
        OrganizeDO organizeDO = organizeDAO.selectById(organizeDTO.getId());
        BeanUtils.copyProperties(organizeDTO,organizeDO);
        String videsName = ValidateCodeUtils.generateCode(4);
        if (!ObjectUtils.isEmpty(organizeDTO.getAvatar())) {
            String imagePath = FileUtils.saveMultipartFile2(organizeDTO.getAvatar(), devHttpPrefix + RESOURCE_PATH_PREFIX + videsName,
                    FileUtils.staticPath + RESOURCE_PATH_PREFIX + videsName);
            organizeDO.setAvatar(imagePath);
        }
        organizeDAO.updateById(organizeDO);
        return Result.success("更新组织成功");
    }

    @Override
    public Result addOrganizePeople(OrganizationVO organizationVO) {
        OrganizeDO organizeDO = organizeDAO.selectById(organizationVO.getOrganizationId());
        List<String> organizePeople = organizeDO.getOrganizePeople();
        for(int i=0;i<organizationVO.getUsername().size();i++){
            organizePeople.add(organizationVO.getUsername().get(i));
        }
        organizeDO.setOrganizePeople(organizePeople);
        return Result.success("添加组织成员成功");
    }

    @Override
    public Result delOrganizePeople(OrganizationVO organizationVO) {
        OrganizeDO organizeDO = organizeDAO.selectById(organizationVO.getOrganizationId());
        List<String> organizePeople = organizeDO.getOrganizePeople();
        for(int i=0;i<organizationVO.getUsername().size();i++){
            organizePeople.remove(organizationVO.getUsername().get(i));
        }
        organizeDO.setOrganizePeople(organizePeople);
        return Result.success("删除组织成员成功");
    }

    @Override
    public Result createOrganizeProject(OrganizationProjectVO organizationProjectVO) {
        ArrayList<String> arrayList = new ArrayList<>();
        GitLabApi gitlabapi = null;
        List<Commit> commits;
        try {
            gitlabapi = GitLabApi.oauth2Login(
                    GITLAB_REMOTE_USERNAME,
                    REMOTE_USERNAME,
                    GITLAB_REMOTE_PWD);
        } catch (GitLabApiException e) {
        }
        Project projectSpec = new Project();
        projectSpec.setName(organizationProjectVO.getProjectName());
        if (StringUtils.isNotEmpty(organizationProjectVO.getProjectDescription())) {
            projectSpec.setDescription(organizationProjectVO.getProjectDescription());
        }
        if (organizationProjectVO.getVisibility().equals("private")) {
            projectSpec.setVisibility(Visibility.PRIVATE);
        }
        if (organizationProjectVO.getVisibility().equals("public")) {
            projectSpec.setVisibility(Visibility.PUBLIC);
        }
        try {
            List<UserProjectDO> userProjectDOS = userProjectDAO.selectByName(organizationProjectVO.getProjectName());
            if (!CollectionUtils.isEmpty(userProjectDOS)) {
                return Result.error(ResultCodeEnum.Name_Repeat);
            }
            projectSpec.setInitializeWithReadme(organizationProjectVO.getIsInit());
            projectSpec.setDefaultBranch("master");
            Project project = gitlabapi.getProjectApi().createProject(3, projectSpec);
            UserProjectDO userProjectDO = new UserProjectDO();
            BeanUtils.copyProperties(organizationProjectVO, userProjectDO);
            userProjectDO.setProjectId(project.getId());
            userProjectDO.setDefaultBranch(project.getDefaultBranch());
            Visibility visibility = project.getVisibility();
            userProjectDO.setVisibility(visibility.toString());
            String webUrl = project.getWebUrl();
            String url = "git remote add origin" + webUrl + ".git\n";
            userProjectDO.setProjectLink(project.getWebUrl() + ".git");
            userProjectDO.setSshLink(project.getSshUrlToRepo());
            HashMap<String, String> map = new HashMap<>();
            ArrayList<String> arr = new ArrayList<>();
            userProjectDO.setPraiseUser(arr);
            userProjectDO.setCollaboration(map);
            UserDO userDO = userDAO.selectByUsername(organizationProjectVO.getUsername());
            userProjectDO.setAvatar(userDO.getAvatar());
            commits = gitlabapi.getCommitsApi().getCommits(project.getId());
            if(organizationProjectVO.getIsInit()){
                Commit commit = commits.get(commits.size() - 1);
                if(commit!=null){
                    Date committedDate = commit.getCommittedDate();
                    String format = DateUtils.format(committedDate, DateUtils.YYYY_MM_DD_HH_MM_SS);
                    userProjectDO.setCommittedDate(format);
                    userProjectDO.setCommittedMessage(commit.getMessage());
                }else {
                    userProjectDO.setCommittedDate(null);
                    userProjectDO.setCommittedMessage(null);
                }
            }
            userProjectDAO.insert(userProjectDO);
            OrganizeProjectDO organizeProjectDO = new OrganizeProjectDO();
            organizeProjectDO.setOrganizeId(organizationProjectVO.getOrganizationId());
            organizeProjectDO.setOrganizeName(organizationProjectVO.getOrganizationName());
            organizeProjectDO.setProjectId(project.getId());
            organizeProjectDO.setProjectName(organizationProjectVO.getProjectName());
            organizeProjectDAO.insert(organizeProjectDO);
            if (organizationProjectVO.getIsInit()) {
                arrayList.add(initFile0);
                arrayList.add(initFile);
                String steer = "git init\n" +
                        "cd existing_repo\n" +
                        url +
                        "git branch -M main\n" +
                        "git push -uf origin main";
                arrayList.add(steer);
            } else {
                String steer = "git init\n" +
                        "cd existing_repo\n" +
                        url +
                        "git branch -M main\n" +
                        "git push -uf origin main";
                arrayList.add(steer);
            }
            arrayList.add(String.valueOf(project.getId()));
        } catch (GitLabApiException e) {
        }
        return Result.success(arrayList);
    }

    @Override
    public Result showUserOrganizes(HttpServletRequest request) {
        String username = JwtUtils.getUsername(request);
        List<OrganizeDO> organizeDOS = organizeDAO.selectByUserName(username);
        return Result.success(organizeDOS);
    }

    @Override
    public Result showUserOrganizesPen(HttpServletRequest request, Integer organizeId) {
        OrganizeDO organizeDO = organizeDAO.selectById(organizeId);
        return Result.success(organizeDO.getOrganizePeople());
    }

    @Override
    public Result showUserOrganizeProject(Integer organizeId) {
        List<OrganizeProjectDO> organizeProjectDOS = organizeProjectDAO.selectByOrganizeId(organizeId);
        List<Integer> projectIds = organizeProjectDOS.stream().map(item -> item.getProjectId()).collect(Collectors.toList());
        List<UserProjectDO> userProjectDOS = userProjectDAO.selectInProjectId(projectIds);
        return Result.success(userProjectDOS);
    }
}
